package com.example.rpcdemo.rpc.server;

import com.example.rpcdemo.rpc.RpcRequest;
import com.example.rpcdemo.rpc.RpcResponse;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class RpcServerHandler extends ChannelInboundHandlerAdapter {
    
    private final Map<String, Object> serviceMap = new ConcurrentHashMap<>();
    
    public void addService(String serviceName, Object service) {
        serviceMap.put(serviceName, service);
    }
    
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        RpcRequest request = (RpcRequest) msg;
        RpcResponse response = new RpcResponse();
        
        try {
            Object result = handleRequest(request);
            response.setResult(result);
        } catch (Exception e) {
            response.setError(e.getMessage());
        }
        
        ctx.writeAndFlush(response);
    }
    
    private Object handleRequest(RpcRequest request) throws Exception {
        String className = request.getClassName();
        Object service = serviceMap.get(className);
        
        if (service == null) {
            throw new RuntimeException("Service not found: " + className);
        }
        
        Class<?> clazz = service.getClass();
        Method method = clazz.getMethod(request.getMethodName(), request.getParameterTypes());
        
        return method.invoke(service, request.getArgs());
    }
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}